#pragma once
#include <unordered_set>
#include "Log.hpp"
#include "InetArr.hpp"

using namespace LogModule;

class User
{
public:
    User(uint16_t port, std::string ip) : _inetAddr(port, ip)
    {
    }
    void SendTo(int sockfd, const std::string &message)
    {
        ::sendto(sockfd, message.c_str(), message.size(), 0, _inetAddr.NetAddr(), _inetAddr.NetAddrLen());
        LOG(LogLevel::INFOMATION) << "转发到:" << Addr() << "信息为：" << message;
    }

    std::string Addr()
    {
        return _inetAddr.Addr();
    }

    bool operator==(User &user)
    {
        return Addr() == user.Addr();
    }

    size_t hash() 
    {
        size_t ret = 0;
        std::string s=_inetAddr.Addr();
        for (char c : s)
        {
            ret = static_cast<unsigned char>(c) + (ret << 6) + (ret << 16) - ret;
        }
        return ret;
    }

private:
    InetAddr _inetAddr;
};

struct UserPtrHash
{
    size_t operator()(const std::shared_ptr<User> &ptr) const
    {
        return ptr->hash(); // 调用 User 的哈希
    }
};

struct UserPtrEqual
{
    bool operator()(const std::shared_ptr<User> &lhs, const std::shared_ptr<User> &rhs) const
    {
        return *lhs == *rhs; // 调用 User 的 operator==
    }
};

class UserManage
{
public:
    void AddUser(InetAddr inetAddr)
    {
        LockGuard lockguard(_lock);
        std::shared_ptr<User> tmp = std::make_shared<User>(inetAddr.Port(), inetAddr.Ip());
        if (_userMessage.count(tmp) == 0)
        {
            _userMessage.emplace(tmp);
            LOG(LogLevel::INFOMATION) << inetAddr.Addr() << "添加成功....";
        }
        else
        {
            //LOG(LogLevel::WARNING) << inetAddr.Addr() << "已经存在....";
        }
    }
    void DeleteUser(InetAddr inetAddr)
    {
        LockGuard lockguard(_lock);
        std::shared_ptr<User> tmp = std::make_shared<User>(inetAddr.Port(), inetAddr.Ip());
        if (_userMessage.count(tmp) == 0)
        {
            LOG(LogLevel::WARNING) << inetAddr.Addr() << "不存在....";
        }
        else
        {
            _userMessage.erase(tmp);
            LOG(LogLevel::WARNING) << inetAddr.Addr() << "删除成功....";
        }
    }
    void Route(int sockfd, const std::string &message)
    {
        LockGuard lockguard(_lock);
        for (auto &e : _userMessage)
        {
            e->SendTo(sockfd, message);
        }
    }

private:
    std::unordered_set<std::shared_ptr<User>, UserPtrHash, UserPtrEqual> _userMessage;
    Mutex _lock; // 加锁 保护
};
